﻿using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Text;
using Snowdreamist.ComponentModel.Plugin;

namespace Snowdreamist.Windows.Navigation.Primitives
{
    public class UriMapperRepository
    {
        private static readonly ImportedPluginProperty<IUriMapper> MappersProperty
            = ImportedPluginProperty.Create<IUriMapper>(
                new ContractMetadata(new Guid("63ED4B86-F197-407F-A812-6A1DAB6F562A"), null, typeof(IUriMapper), CandidateMode.ZeroOrMore, typeof(UriMapperRepository)
                ));

        public UriMapperRepository()
        {
            // add composed mapper
            if (this.ComposedMappers != null)
                foreach (var mapper in this.ComposedMappers)
                    try
                    {
                        this.AddMapper(mapper);
                    }
                    catch (Exception error)
                    {
                        // log
                    }

            this.Mappers = new ReadOnlyCollection<IUriMapper>(this._mappers);
        }

        public void AddMapper(IUriMapper mapper)
        {
            if (mapper == null)
                throw new ArgumentNullException("mapper");
            lock (this)
            {
                if (this._mappers.Contains(mapper))
                    throw new ValueExistsException("Mapper already exists");
                this._mappers.Add(mapper);
            }
        }

        public void RemoveMapper(IUriMapper mapper)
        {
            if (mapper == null)
                throw new ArgumentNullException("mapper");
            lock (this)
            {
                this._mappers.Remove(mapper);
            }
        }

        public ReadOnlyCollection<IUriMapper> Mappers { get; private set; }

        #region private

        private readonly List<IUriMapper> _mappers = new List<IUriMapper>();

        private IEnumerable<IUriMapper> ComposedMappers
        {
            get
            {
                return MappersProperty.GetValues(this);
            }
        }

        #endregion private
    }
}